﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Esign.Net.Input;
using Esign.Net.Output;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using RestSharp;

namespace Esign.Net
{
    public static class RequestBase
    {
        /// <summary>
        /// 通用请求
        /// </summary>
        /// <typeparam name="TInput"></typeparam>
        /// <typeparam name="TOutput"></typeparam>
        /// <param name="t"></param>
        /// <param name="havePar">是否有参数</param>
        /// <exception cref="Exception"></exception>
        /// <returns></returns>
        public static TOutput Execute<TInput, TOutput>(this TInput t,bool havePar=true) where TInput : InputBase
        {
            // 请求参数JSON字符串
            string reqData = JsonConvert.SerializeObject(t);
            if (reqData == "{}" || !havePar)
            {
                reqData = string.Empty;
            }

            string HTTPMethod = Enum.GetName(typeof(Method), t.ReqType).ToUpper();//HTTP的请求方法，全部大写，例如：GET、POST。
            string Accept = "*/*";
            string ContentMD5 = reqData.Length==0?"":DigestHelper.doContentMD5(reqData);//在请求Body体存在数据且非 Form 格式时，必须对Body体计算
            string ContentType = reqData.Length == 0 ? "" : "application/json; charset=UTF-8";
            string Date = "";
            string Headers = "";
            string PathAndParameters = t.Url;
            // 组合拼接待签名字符串
            StringBuilder sb = new StringBuilder();
            sb.Append(HTTPMethod).Append("\n").Append(Accept).Append("\n").Append(ContentMD5).Append("\n")
                .Append(ContentType).Append("\n").Append(Date).Append("\n");
            if (Headers.Length==0)
            {
                sb.Append(Headers).Append(PathAndParameters);
            }
            else
            {
                sb.Append(Headers).Append("\n").Append(PathAndParameters);
            }


            var client = new RestClient(t.ConfigInfo.Host + t.Url);
            client.Timeout = -1;
            var request = new RestRequest(t.ReqType);


            var signature = DigestHelper.doSignatureBase64(sb.ToString(), t.ConfigInfo.AppSecret);

            request.AddHeader("X-Tsign-Open-App-Id", t.ConfigInfo.AppId);
            request.AddHeader("X-Tsign-Open-Auth-Mode", "Signature");
            request.AddHeader("X-Tsign-Open-Ca-Signature", signature);
            request.AddHeader("X-Tsign-Open-Ca-Timestamp", DigestHelper.GetTimestamp().ToString());
            request.AddHeader("Accept", Accept);

            if (!string.IsNullOrEmpty(reqData))
            {
                request.AddHeader("Content-Type", ContentType);
            }

            request.AddHeader("Content-MD5", ContentMD5);


            request.AddParameter("application/json", reqData ?? "", ParameterType.RequestBody);
            IRestResponse response = client.Execute(request);

            try
            {
                var result = JsonConvert.DeserializeObject<TOutput>(response.Content);
                return result;
            }
            catch (Exception e)
            {
                throw new JsonReaderException("接口实体转换异常,原json内容:"+ response.Content);
            }
           
        }


    }
}
